﻿#region Using Statements
using System;
using GameBase.Sprites;
using Microsoft.Xna.Framework;
using StarFox.ScreenComponents;
#endregion

namespace StarFox.Screens
{
    /// <summary>
    /// Basic properties needed to implement any game menu.
    /// </summary>
    public class SimpleMenu : ScreenComponent2D
    {
        #region Fields

        // sprite sheet
        SpriteSheet spriteSheet;

        // starfox logo
        Rectangle dstRectStarFox;
        Rectangle dstRectXna;

        // menu title
        string menuTitle;
        Point initPosMenuTitle;
        Point endPosMenuTitle;
        Rectangle dstRectMenuTitle;

        // buttons
        Point initPosBtn;
        Point endPosBtn;
        Rectangle dstRectBtn;

        // button messages
        Point initPosBtn_Msg;
        Point endPosBtn_Msg;
        Rectangle dstRectBtn_Msg;

        #endregion

        #region Properties

        /// <summary>
        /// Sets the menu title.
        /// </summary>
        public string MenuTitle
        {
            set
            {
                menuTitle = value;

                Rectangle auxRect = spriteSheet.SourceRectangle(menuTitle);
                dstRectMenuTitle = Rectangle.Empty;
                dstRectMenuTitle.Width = (int)(auxRect.Width * Screen.Scale);
                dstRectMenuTitle.Height = (int)(auxRect.Height * Screen.Scale);
                initPosMenuTitle = new Point((int)(Screen.Width * 0.05f), -dstRectMenuTitle.Height);
                endPosMenuTitle = new Point(initPosMenuTitle.X, (int)(Screen.Height * 0.06f));
                dstRectMenuTitle.Location = initPosMenuTitle;
            }
        }

        #endregion

        #region Screen Transitions

        bool toVisible = false;
        bool toHidden = false;
        float trTime = 0.0f;

        /// <summary>
        /// Makes the ScreenComponent2D transition to visible state.
        /// </summary>
        public override void Show()
        {
            toVisible = true;
        }

        /// <summary>
        /// Makes the ScreenComponent2D transition to hidden state.
        /// </summary>
        public override void Hide()
        {
            toHidden = true;
        }

        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of this class.
        /// </summary>
        /// <param name="screen">The Screen that this ScreenComponent2D is associated to.</param>
        public SimpleMenu(StarFoxScreen screen)
            : base(screen)
        {
            #region Asset Loading

            spriteSheet = Game.Content.Load<SpriteSheet>(ContentSettings.GetAsset("MENU_SPRITES"));

            #endregion

            #region Sprites

            Rectangle auxRect;

            // logo
            auxRect = spriteSheet.SourceRectangle("LOGO_STARFOX_SMALL");
            dstRectStarFox = new Rectangle((int)(0.675f * Screen.Width), (int)(0.75f * Screen.Height), (int)(auxRect.Width * Screen.Scale), (int)(auxRect.Height * Screen.Scale));
            auxRect = spriteSheet.SourceRectangle("LOGO_XNA_SMALL");
            dstRectXna = new Rectangle(0, 0, (int)(auxRect.Width * Screen.Scale), (int)(auxRect.Height * Screen.Scale));
            dstRectXna.Location = new Point(dstRectStarFox.Right - (int)(auxRect.Width * Screen.Scale), dstRectStarFox.Bottom + (int)(dstRectStarFox.Height * 0.75f));

            // initialization - buttons
            initPosBtn = new Point();
            initPosBtn_Msg = new Point();
            endPosBtn = new Point();
            endPosBtn_Msg = new Point();
            dstRectBtn = new Rectangle();
            dstRectBtn_Msg = new Rectangle();

            // buttons
            auxRect = spriteSheet.SourceRectangle("BUTTON_B");
            dstRectBtn = new Rectangle(0, 0, (int)(auxRect.Width * Screen.Scale), (int)(auxRect.Height * Screen.Scale));
            initPosBtn = new Point((int)(Screen.Width * 0.05f), Screen.Height);
            endPosBtn = new Point(initPosBtn.X, (int)(Screen.Height * 0.9f));
            dstRectBtn.Location = initPosBtn;
            
            // button messages
            auxRect = spriteSheet.SourceRectangle("BUTTON_BACK");
            dstRectBtn_Msg = new Rectangle(0, 0, (int)(auxRect.Width * Screen.Scale), (int)(auxRect.Height * Screen.Scale));
            Point auxBtnGap = new Point((int)(Screen.Width * 0.05f), (int)((dstRectBtn_Msg.Height - dstRectBtn.Height) / 2));
            initPosBtn_Msg = new Point(initPosBtn.X + auxBtnGap.X, initPosBtn.Y - auxBtnGap.Y);
            endPosBtn_Msg = new Point(initPosBtn_Msg.X, endPosBtn.Y - auxBtnGap.Y);
            dstRectBtn_Msg.Location = initPosBtn_Msg;

            #endregion
        }

        #endregion

        #region Update

        /// <summary>
        /// Called when the ScreenComponent2D needs to be updated.
        /// </summary>
        /// <param name="gameTime">Time elapsed since the last call to this method.</param>
        public override void Update(GameTime gameTime)
        {
            #region Player Input

            if (Screen.InputEnabled)
            {
                // cancellation
                if (Screen.PlayerInput.IsMenuBack(Screen.PlayerIndex))
                {
                    // go to the previous screen
                    Screen.ScreenSound.Cancel();
                    Screen.ScreenManager.RemoveScreen(Screen);
                }
            }

            #endregion

            #region Screen Transition

            if (toVisible)
            {
                // update items position
                float auxTrTime = 1.0f - (float)Math.Pow(1.0f - trTime, 2);
                // menu title
                dstRectMenuTitle.Y = initPosMenuTitle.Y + (int)(Math.Abs(initPosMenuTitle.Y - endPosMenuTitle.Y) * auxTrTime);
                // buttons
                dstRectBtn.Y = initPosBtn.Y - (int)(Math.Abs(initPosBtn.Y - endPosBtn.Y) * auxTrTime);
                dstRectBtn_Msg.Y = initPosBtn_Msg.Y - (int)(Math.Abs(initPosBtn_Msg.Y - endPosBtn_Msg.Y) * auxTrTime);

                // update transition timer
                float trDelta = (float)(gameTime.ElapsedGameTime.TotalMilliseconds / Time.TotalMilliseconds);
                trTime += trDelta;
                trTime = MathHelper.Clamp(trTime, 0.0f, 1.0f);
                if (trTime == 1.0f) { toVisible = false; trTime = 0.0f; }
            }
            else if (toHidden)
            {
                // update items position
                float auxTrTime = (float)Math.Pow(trTime, 2);
                // menu title
                dstRectMenuTitle.Y = endPosMenuTitle.Y - (int)(Math.Abs(initPosMenuTitle.Y - endPosMenuTitle.Y) * auxTrTime);
                // buttons
                dstRectBtn.Y = (int)(endPosBtn.Y + Math.Abs(initPosBtn.Y - endPosBtn.Y) * auxTrTime);
                dstRectBtn_Msg.Y = (int)(endPosBtn_Msg.Y + Math.Abs(initPosBtn_Msg.Y - endPosBtn_Msg.Y) * auxTrTime);

                // update transition timer
                float trDelta = (float)(gameTime.ElapsedGameTime.TotalMilliseconds / Time.TotalMilliseconds);
                trTime += trDelta;
                trTime = MathHelper.Clamp(trTime, 0.0f, 1.0f);
                if (trTime == 1.0f) { toHidden = false; trTime = 0.0f; }
            }

            #endregion
        }

        #endregion

        #region Draw

        /// <summary>
        /// Called when the ScreenComponent2D needs to be drawn.
        /// </summary>
        /// <param name="gameTime">Time elapsed since the last call to this method.</param>
        public override void Draw(GameTime gameTime)
        {
            // logo
            SpriteBatch.Draw(spriteSheet.Texture, dstRectStarFox, spriteSheet.SourceRectangle("LOGO_STARFOX_SMALL"), Color.Red);
            SpriteBatch.Draw(spriteSheet.Texture, dstRectXna, spriteSheet.SourceRectangle("LOGO_XNA_SMALL"), Color.Red);

            // title
            SpriteBatch.Draw(spriteSheet.Texture, dstRectMenuTitle, spriteSheet.SourceRectangle(menuTitle), Color.Yellow);

            // buttons
            SpriteBatch.Draw(spriteSheet.Texture, dstRectBtn, spriteSheet.SourceRectangle("BUTTON_B"), Color.Red);
            SpriteBatch.Draw(spriteSheet.Texture, dstRectBtn_Msg, spriteSheet.SourceRectangle("BUTTON_BACK"), Color.Yellow);
        }

        #endregion
    }
}
